#include "EnemyFactory.h"
#include "CNumber.h"
#include "StrategyBank.h"
#include "Config.h"
#include "SpriteAnimation.h"
#include "xml_node_store.h"
#include "EnemyActionFactory.h"
#include "PoolObject.h"
#include "xml_tag.h"



EnemyFactory::EnemyFactory(void)
{
	_id = NULL;
	_strategy = NULL;
	_listResource = NULL;
}


EnemyFactory::~EnemyFactory(void)
{
	CC_SAFE_RELEASE(_id);
	CC_SAFE_RELEASE(_strategy);
	CC_SAFE_RELEASE(_listResource);
}

void EnemyFactory::parseXml( xml_node node )
{
	char* id = (char*)node.child(XMLTAG_ID).text().as_string();
	int boundWidth = node.child(XMLTAG_BOUND).child(XMLTAG_WIDTH).text().as_int();
	int boundHeight = node.child(XMLTAG_BOUND).child(XMLTAG_HEIGHT).text().as_int();
	CCSize bound = CCSizeMake(boundWidth, boundHeight);

	xml_node sources = node.child(XMLTAG_RESOURCES);
	for (xml_node j = sources.child(XMLTAG_RESOURCE); j; j = j.next_sibling(XMLTAG_RESOURCE))
	{
		CCDictionary* _resource = CCDictionary::create();
		char* sType = (char*)j.child(XMLTAG_RESOURCE_TYPE).text().as_string();
		int sPosX = j.child(XMLTAG_RESOURCE_POSITION).child(XMLTAG_X).text().as_int();
		int sPosY = j.child(XMLTAG_RESOURCE_POSITION).child(XMLTAG_Y).text().as_int();
		float sScaleX = j.child(XMLTAG_RESOURCE_SCALE).child(XMLTAG_X).text().as_float();
		float sScaleY = j.child(XMLTAG_RESOURCE_SCALE).child(XMLTAG_Y).text().as_float();

		xml_node nAnchorPoint = j.child(XMLTAG_RESOURCE_ANCHORPOINT);
		if (nAnchorPoint.root())
		{
			float sAnchorX = nAnchorPoint.child(XMLTAG_X).text().as_float();
			float sAnchorY = nAnchorPoint.child(XMLTAG_Y).text().as_float();
			
			_resource->setObject(CCNumber<CCPoint>::create(ccp(sAnchorX, sAnchorY)), XMLTAG_RESOURCE_ANCHORPOINT);
		} else
			_resource->setObject(CCNumber<CCPoint>::create(CCPointZero), XMLTAG_RESOURCE_ANCHORPOINT);

		xml_node nAction = j.child(XMLTAG_RESOURCE_ACTION);
		CCDictionary* sAction = CCDictionary::create();
		if (nAction.root())
		{
			char* aId = (char*)nAction.child(XMLTAG_ID).text().as_string();
			string data = XmlUtil::node_to_string(nAction.child(XMLTAG_RESOURCE_DATA));
			sAction->setObject(ccs(aId), XMLTAG_ID);
			sAction->setObject(CCNumber<string>::create(data), XMLTAG_RESOURCE_DATA);
			_resource->setObject(sAction, XMLTAG_RESOURCE_ACTION);
		}

		if (strcmp(sType, RESOURCE_SPRITE) == 0)
		{
			char* spriteFrame = (char*)j.child(XMLTAG_RESOURCE_SPRITEFRAME).text().as_string();
			_resource->setObject(ccs(spriteFrame), XMLTAG_RESOURCE_SPRITEFRAME);
		} else if (strcmp(sType, RESOURCE_SPRITEANIMATION) == 0)
		{
			char* texture = (char*)j.child(XMLTAG_RESOURCE_TEXTURE).text().as_string();
			char* plist = (char*)j.child(XMLTAG_RESOURCE_PLIST).text().as_string();
			char* prefix = (char*)j.child(XMLTAG_RESOURCE_PREFIX).text().as_string();
			int from = j.child(XMLTAG_RESOURCE_FROM).text().as_int();
			int to = j.child(XMLTAG_RESOURCE_TO).text().as_int();

			_resource->setObject(ccs(texture), XMLTAG_RESOURCE_TEXTURE);
			_resource->setObject(ccs(plist), XMLTAG_RESOURCE_PLIST);
			_resource->setObject(ccs(prefix), XMLTAG_RESOURCE_PREFIX);
			_resource->setObject(CCNumber<int>::create(from), XMLTAG_RESOURCE_FROM);
			_resource->setObject(CCNumber<int>::create(to), XMLTAG_RESOURCE_TO);
		} else if (strcmp(sType, RESOURCE_PARTICLE) == 0)
		{
			char* fileName = (char*)j.child(XMLTAG_RESOURCE_FILENAME).text().as_string();
			_resource->setObject(ccs(fileName), XMLTAG_RESOURCE_FILENAME);
		}

		
		_resource->setObject(ccs(sType), XMLTAG_RESOURCE_TYPE);
		_resource->setObject(CCNumber<CCPoint>::create(ccp(sPosX, sPosY)), XMLTAG_RESOURCE_POSITION);
		_resource->setObject(CCNumber<CCPoint>::create(ccp(sScaleX, sScaleY)), XMLTAG_RESOURCE_SCALE);

		_listResource->addObject(_resource);
	}

	setId(ccs(id));
	setBound(bound);
}

bool EnemyFactory::init()
{
	setResources(CCArray::create());
	setStrategy(ccs(STRATEGY_DEFAULT)); // Default strategy for enemy
	return true;
}

Enemy* EnemyFactory::createEnemy()
{
	//Enemy* enemy = Enemy::create();
	Enemy* enemy = PoolObject<Enemy>::sharedPoolObject()->getObjectWithId(_id->getCString());

	if (enemy->getId() != NULL)
		return enemy;

	enemy->setId(_id);
	
	CCObject* it;
	CCARRAY_FOREACH(_listResource, it)
	{
		CCDictionary* source = dynamic_cast<CCDictionary*>(it);
		char* sType = (char*)dynamic_cast<CCString*>(source->objectForKey(XMLTAG_RESOURCE_TYPE))->getCString();
		CCPoint sPos = dynamic_cast<CCNumber<CCPoint>*>(source->objectForKey(XMLTAG_RESOURCE_POSITION))->getNumber();
		CCPoint sScale = dynamic_cast<CCNumber<CCPoint>*>(source->objectForKey(XMLTAG_RESOURCE_SCALE))->getNumber();
		CCPoint sAnchorPoint = dynamic_cast<CCNumber<CCPoint>*>(source->objectForKey(XMLTAG_RESOURCE_ANCHORPOINT))->getNumber();

		if (strcmp(sType, RESOURCE_SPRITE) == 0)
		{
			char* spriteFrame = (char*)dynamic_cast<CCString*>(source->objectForKey(XMLTAG_RESOURCE_SPRITEFRAME))->getCString();

			CCSprite* sprite = CCSprite::createWithSpriteFrameName(spriteFrame);
			sprite->setAnchorPoint(sAnchorPoint);
			sprite->setPosition(sPos);
			sprite->setScaleX(sScale.x);
			sprite->setScaleY(sScale.y);
			// FOr action
			CCDictionary* sAction = dynamic_cast<CCDictionary*>(source->objectForKey(XMLTAG_RESOURCE_ACTION));
			if (sAction)
			{
				char* aId = (char*)dynamic_cast<CCString*>(sAction->objectForKey(XMLTAG_ID))->getCString();
				string data = dynamic_cast<CCNumber<string>*>(sAction->objectForKey(XMLTAG_RESOURCE_DATA))->getNumber();
				CCAction* action = EnemyActionFactory::sharedActionFactory()->createAction(aId, data);
				sprite->runAction(action);
				sprite->setTag(TAG_SPRITEWITHACTION);
			}

			enemy->addChild(sprite);
		}
		else if (strcmp(sType, RESOURCE_SPRITEANIMATION) == 0)
		{
			char* texture = (char*)dynamic_cast<CCString*>(source->objectForKey(XMLTAG_RESOURCE_TEXTURE))->getCString();
			char* plist = (char*)dynamic_cast<CCString*>(source->objectForKey(XMLTAG_RESOURCE_PLIST))->getCString();
			char* prefix = (char*)dynamic_cast<CCString*>(source->objectForKey(XMLTAG_RESOURCE_PREFIX))->getCString();

			int from = dynamic_cast<CCNumber<int>*>(source->objectForKey(XMLTAG_RESOURCE_FROM))->getNumber();
			int to = dynamic_cast<CCNumber<int>*>(source->objectForKey(XMLTAG_RESOURCE_TO))->getNumber();

			SpriteAnimation* spriteAni1 = SpriteAnimation::createWith(texture, plist, prefix, from, to);
			spriteAni1->playAnimation(true);
			spriteAni1->setPosition(sPos);
			spriteAni1->setScaleX(sScale.x);
			spriteAni1->setScaleY(sScale.y);
			spriteAni1->setTag(TAG_SPRITEANIMATION);
			enemy->addChild(spriteAni1);
		} else if (strcmp(sType, RESOURCE_PARTICLE) == 0)
		{
			char* fileName = (char*)dynamic_cast<CCString*>(source->objectForKey(XMLTAG_RESOURCE_FILENAME))->getCString();
			CCParticleSystemQuad* particle = CCParticleSystemQuad::create(fileName);
			particle->setPosition(sPos);
			particle->setScaleX(sScale.x);
			particle->setScaleY(sScale.y);
			enemy->addChild(particle);
		}
	}
	enemy->setContentSize(_bound);
	enemy->getHealthBar()->setScaleX(enemy->boundingBox().size.width / enemy->getHealthBar()->boundingBox().size.width);

	return enemy;
}
